package springinpractice.ch8.contact.web;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import springinpractice.ch8.contact.model.UserMessage;
import springinpractice.ch8.contact.service.ContactService;
import springinpractice.common.util.ValidationUtil;

/**
 * @author Willie Wheeler and John Wheeler
 * Book : 'Spring In Practice' [Book written by Willie Wheeler and John Wheeler]
 **/

@Controller
public final class ContactController {
	private ContactService contactService;
	private Validator validator;
	
	
	// ========================================================================
	// Dependency injection methods
	// ========================================================================
	
	@Required
	public void setContactService(ContactService contactService) {
		this.contactService = contactService;
	}

	@Required
	public void setValidator(Validator validator) {
		this.validator = validator;
	}
	
	
	// ========================================================================
	// Init binders
	// ========================================================================

	@InitBinder
	public void initBinder(WebDataBinder binder) {
		binder.setAllowedFields(new String[] {
			"name", "email", "text", "referer"
		});
	}
	
	
	// ========================================================================
	// Service methods
	// ========================================================================
	
	@RequestMapping(method = RequestMethod.GET)
	public void form(HttpServletRequest req, Model model) {
		UserMessage userMsg = new UserMessage();
		userMsg.setReferer(req.getHeader("Referer"));
		model.addAttribute(userMsg);
	}
	
	@RequestMapping(method = RequestMethod.POST)
	public String form(HttpServletRequest req,
			@ModelAttribute("userMessage") UserMessage userMsg,
			BindingResult result) {
		
		ValidationUtil.verifyBinding(result);
		
		validator.validate(userMsg, result);
		if (result.hasErrors()) {
			result.reject("global.error");
			return "contact/form";
		}
		
		userMsg.setIpAddress(req.getRemoteAddr());
		userMsg.setAcceptLanguage(req.getHeader("Accept-Language"));
		userMsg.setUserAgent(req.getHeader("User-Agent"));
		userMsg.setDateCreated(new Date());
		
		// This not only saves the message, but also e-mails the user with a
		// confirmation message and the admin with the user message.
		contactService.saveUserMessage(userMsg);
		
		// Use the redirect-after-post pattern to reduce double-submits.
		return "redirect:thanks.html";
	}
	
	@RequestMapping
	public void thanks() {
	}
}
